package services;

import javax.transaction.Transactional;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.encoding.Md5PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import repositories.AdministratorRepository;
import security.Authority;
import security.LoginService;
import security.UserAccount;
import domain.Administrator;
import forms.AdministratorForm;

@Service
@Transactional
public class AdministratorService {

	@Autowired
	private AdministratorRepository administratorRepository;
	
	// Supporting Services
	
	@Autowired
	private UserService userService;

	public AdministratorService() {
		super();
	}

	// Simple CRUD methods
	public Administrator create() {
		Administrator result;
		UserAccount userAccount;
		Authority authority;

		authority = new Authority();

		userAccount = new UserAccount();
		authority.setAuthority("ADMINISTRATOR");
		userAccount.addAuthority(authority);

		result = new Administrator();
		result.setUserAccount(userAccount);

		return result;
	}

	public void save(Administrator administrator) {
		Assert.notNull(administrator);
		if(administrator.getId()==0){
			Assert.isNull(findByUsername(administrator.getUserAccount().getUsername()));
		}
		Assert.isNull(userService.findByUsername(administrator.getUserAccount().getUsername()));

		administratorRepository.save(administrator);
	}

	public Administrator findOne(int administratorId){
		Administrator result;
		
		result = administratorRepository.findOne(administratorId);
		
		return result;
	}
	
	// Other Business Methods
	public Administrator findByPrincipal() {
		Administrator result;
		UserAccount userAccount;

		userAccount = LoginService.getPrincipal();
		Assert.notNull(userAccount);

		result = findByUserAccount(userAccount);
		Assert.notNull(result);

		return result;
	}

	public Administrator findByUserAccount(UserAccount userAccount) {
		Assert.notNull(userAccount);
		Administrator result;

		result = administratorRepository.findByUserAccountId(userAccount
				.getId());

		return result;
	}
	
	public Administrator findByUsername (String username){
		Assert.notNull(username);
		Administrator result;
		result = administratorRepository.findByUsername(username);
		return result;
	}

	// Reconstruction method
	public Administrator reconstruct(AdministratorForm administratorForm) {
		Assert.notNull(administratorForm);
		Administrator result;
		Md5PasswordEncoder encoder = new Md5PasswordEncoder();
		String password = administratorForm.getPassword();
		String hash = encoder.encodePassword(password, null);

		result = create();
		result.getUserAccount().setUsername(administratorForm.getUsername());
		result.getUserAccount().setPassword(hash);
		result.setName(administratorForm.getName());
		result.setSurname(administratorForm.getSurname());
		result.setEmail(administratorForm.getEmail());

		return result;
	}
}
